package cn.signalpha.modules.shop.service;

import cn.signalpha.core.tool.utils.BeanUtil;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.core.tool.utils.StringPool;
import cn.signalpha.core.tool.utils.StringUtil;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.pay.dto.SettleOrderDTO;
import cn.signalpha.modules.pay.dto.SettleUserDTO;
import cn.signalpha.modules.pay.provider.IPayGranter;
import cn.signalpha.modules.pay.provider.PayGranterBuilder;
import cn.signalpha.modules.pay.vo.SettleOrderVO;
import cn.signalpha.modules.pay.vo.SettleUserVO;
import cn.signalpha.modules.shop.entity.OrderSettlePlace;
import cn.signalpha.modules.shop.entity.enums.OrderSettleWayEnum;
import cn.signalpha.modules.shop.excel.OrderSettlePlaceExcel;
import cn.signalpha.modules.shop.mapper.OrderSettlePlaceMapper;
import cn.signalpha.modules.shop.vo.OrderSettlePlaceVO;
import cn.signalpha.modules.shop.vo.PlaceVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 服务类
 *
 * @author signalpha
 */
@Service
@AllArgsConstructor
public class OrderSettlePlaceService extends ServiceImpl<OrderSettlePlaceMapper, OrderSettlePlace> {

	private final UserService userService;

	/**
	 * 自定义分页
	 */
    public IPage<OrderSettlePlaceVO> selectOrderSettlePlacePage(IPage<OrderSettlePlaceVO> page, Map<String, Object> params) {
        return page.setRecords(baseMapper.selectOrderSettlePlacePage(page, params));
    }

    /**
	 * 自定义导出
	 */
    public List<OrderSettlePlaceExcel> selectOrderSettlePlaceExcel(Map<String, Object> params) {
        return BeanUtil.copy(baseMapper.selectOrderSettlePlacePage(null, params), OrderSettlePlaceExcel.class);
    }

	/**
	 * 自定义统计
	 */
	public Double selectOrderSettlePlaceTotal(Map<String, Object> params) {
		return baseMapper.selectOrderSettlePlaceTotal(params);
	}

    /**
	 * 自定义Wrappers
	 */
    public QueryWrapper<OrderSettlePlace> selectOrderSettlePlaceWrapper(Map<String, Object> params) {
        QueryWrapper<OrderSettlePlace> wrapper = Wrappers.query();
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("userId")), OrderSettlePlace::getUserId, params.get("userId"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("sellerId")), OrderSettlePlace::getSellerId, params.get("sellerId"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("orderNo")), OrderSettlePlace::getOrderNo, params.get("orderNo"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("orderUserId")), OrderSettlePlace::getOrderUserId, params.get("orderUserId"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("payNo")), OrderSettlePlace::getPayNo, params.get("payNo"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("payBizNo")), OrderSettlePlace::getPayBizNo, params.get("payBizNo"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("payType")), OrderSettlePlace::getPayType, params.get("payType"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("settleType")), OrderSettlePlace::getSettleType, params.get("settleType"));
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("settleStatus")), OrderSettlePlace::getSettleStatus, params.get("settleStatus"));
		wrapper.lambda().ge(ObjectUtil.isNotEmpty(params.get("createTimeBegin")), OrderSettlePlace::getCreateTime, params.get("createTimeBegin"));
		wrapper.lambda().le(ObjectUtil.isNotEmpty(params.get("createTimeEnd")), OrderSettlePlace::getCreateTime, params.get("createTimeEnd"));
        wrapper.lambda().orderByDesc(OrderSettlePlace::getId);
        return wrapper;
    }

	/**
	 * 订单金额统计
	 */
	public Double sumByParams(Map<String, Object> params) {
		return sumByParams(params, "settle_amount");
	}

	/**
	 * 订单金额统计
	 */
	public Double sumByParams(Map<String, Object> params, String field) {
		QueryWrapper<OrderSettlePlace> wrapper = selectOrderSettlePlaceWrapper(params);
		wrapper.select(StringUtil.format("ifnull(sum({}),0) as total", field));
		return Double.valueOf(getMap(wrapper).get("total").toString());
	}

	/**
	 * 订单数量统计
	 */
	public long countByParams(Map<String, Object> params) {
		return count(selectOrderSettlePlaceWrapper(params));
	}

	/**
	 * 支付单号查找
	 */
	public List<OrderSettlePlace> listByOrderNo(String orderNo) {
		return baseMapper.selectList(Wrappers.<OrderSettlePlace>lambdaQuery().eq(OrderSettlePlace::getOrderNo, orderNo));
	}

	/**
	 * 金额排行榜
	 */
	public List<PlaceVO.RankVO> selectOrderRankList(Map<String, Object> params) {
		return baseMapper.selectOrderRankList(params);
	}

	/**
	 * 人数排行榜
	 */
	public List<PlaceVO.RankVO> selectUserRankList(Map<String, Object> params) {
		return baseMapper.selectUserRankList(params);
	}

	/**
	 * 订单结算
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean settleOrder(Serializable id) {
		Date date = new Date();
		OrderSettlePlace orderSettlePlace = baseMapper.selectById(id);

		if(OrderSettleWayEnum.ONE.getCategory() == orderSettlePlace.getSettleWay()){
			if(orderSettlePlace.getSettleAmount() > 0){
				userService.updateUserMoney(WalletDTO.builder()
					.userId(orderSettlePlace.getUserId())
					.amount(orderSettlePlace.getSettleAmount())
					.type(WalletTypeEnum.ADD.getType())
					.sourceId(orderSettlePlace.getOrderNo())
					.sourceType(Objects.requireNonNull(WalletSourceEnum.instance(orderSettlePlace.getSettleType())).getType())
					.remark(Objects.requireNonNull(WalletSourceEnum.instance(orderSettlePlace.getSettleType())).getName())
					.build());
			}
			updateById(OrderSettlePlace.builder().id(orderSettlePlace.getId()).settleStatus(1).settleRemark("结算成功").settleTime(date).build());
			return true;
		}

		if(OrderSettleWayEnum.TOW.getCategory() == orderSettlePlace.getSettleWay()){
			IPayGranter iPayGranter = PayGranterBuilder.getGranter(orderSettlePlace.getPayType());
			//添加分帐方账户
			SettleUserVO settleUserVO = iPayGranter.settleUser(SettleUserDTO.builder().type(2).relationType("STORE").targetId(orderSettlePlace.getUserId()).build());
			if(!Objects.equals(StringPool.YES, settleUserVO.getCode())){
				updateById(OrderSettlePlace.builder().id(orderSettlePlace.getId()).settleStatus(-1).settleRemark("添加分账方失败：" + settleUserVO.getMsg()).settleTime(date).build());
				return false;
			}
			//进行分账
			SettleOrderVO settleOrderVO = iPayGranter.settleOrder(SettleOrderDTO.builder().settleNo(orderSettlePlace.getId().toString()).payBizNo(orderSettlePlace.getPayBizNo()).type(2).targetId(orderSettlePlace.getUserId()).amount(orderSettlePlace.getSettleAmount()).build());
			if(!Objects.equals(StringPool.YES, settleOrderVO.getCode())){
				updateById(OrderSettlePlace.builder().id(orderSettlePlace.getId()).settleStatus(-1).settleRemark("分账失败：" + settleOrderVO.getMsg()).settleTime(date).build());
				return false;
			}else{
				updateById(OrderSettlePlace.builder().id(orderSettlePlace.getId()).settleStatus(1).settleRemark("结算成功，结算单号：" + settleOrderVO.getMsg()).settleTime(date).build());
				return true;
			}
		}
		return false;
	}

}

